﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Xml;
using DingTalk.Api;
using DingTalk.Api.Request;
using DingTalk.Api.Response;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using DingDing.Common;
using DingDing.dingding;
using DingDingAPI;
using System.Collections;
using Newtonsoft.Json;

namespace DingDing.Controllers
{
    /// <summary>
    /// 钉钉接口
    /// </summary>
    /*
        CorpId: ding81ee7d2a6ae2467124f2f5cc6abecb85
        
        应用名称：Test
        suiteId: 11001002
        appId: 47158
        suiteKey: suitet4ezin7rnlbmzswm
        suiteSecret: 3Qt3VwphbHm2M46v0zzozeeJSGbMk_m251-frk64CUmSXMT7Y5G0DmhmHyJvd0Gu
        Token: txd
        数据加密密钥: 0fmjhx398ys8taiwajsx546dmw2towg3v759qvw1l7n

     */

    [Route("[controller]")]
    [ApiController]
    public class CallController : ControllerBase
    {
        string CorpId = "ding81ee7d2a6ae2467124f2f5cc6abecb85";
        string suiteId = "11001002";
        string appId = "47158";
        string suiteKey = "suitet4ezin7rnlbmzswm";
        string suiteSecret = "3Qt3VwphbHm2M46v0zzozeeJSGbMk_m251-frk64CUmSXMT7Y5G0DmhmHyJvd0Gu";
        string Token = "txd";
        public class DingTalkModel
        {
            public string encrypt { get; set; }
        }
        [HttpPost("post/callback")]
        //public JsonResult Callback(string signature, string timestamp, string nonce, [FromBody] DingTalkModel encrypt)
        public string Callback(string signature, string timestamp, string nonce, [FromBody] DingTalkModel encrypt)
        {
            var crypt = new DingTalkCrypt("txd", "0fmjhx398ys8taiwajsx546dmw2towg3v759qvw1l7n", "suitet4ezin7rnlbmzswm");
            string sReplyEchoStr = null;
            int ret = crypt.VerifyURL(signature, timestamp, nonce, encrypt.encrypt, ref sReplyEchoStr);
            string jm = string.Empty;
            crypt.DecryptMsg(signature, timestamp, nonce, encrypt.encrypt, ref jm);

            Hashtable tb = (Hashtable)JsonConvert.DeserializeObject(jm, typeof(Hashtable));
            string eventType = tb["EventType"].ToString();
            LyCommon.WriteLog("eventType: " + eventType);
            string res = "success";
            switch (eventType)
            {
                case "tmp_auth_code":
                    activate_suite(get_permanent_code(tb["AuthCode"].ToString()).PermanentCode);
                    break;
                case "suite_ticket":
                    SuiteTicket = tb["SuiteTicket"].ToString();
                    break;
                default:
                    break;
            }

            timestamp = LyCommon.GetTimestamp(DateTime.UtcNow).ToString();
            string jiami = null;
            string signatureref = null;
            crypt.EncryptMsg(res, timestamp, nonce, ref jiami, ref signatureref);

            Hashtable jsonMap = new Hashtable
                {
                    {"msg_signature", signatureref},
                    {"encrypt", jiami},
                    {"timeStamp", timestamp },
                    {"nonce", nonce}
                };
            string result = JsonConvert.SerializeObject(jsonMap);

            var log = $"执行了CallController:callback : {signature} : {timestamp} : {nonce}\r\nencrypt : {encrypt.encrypt}\r\n解密后的字符串：{jm}";

            LyCommon.WriteLog(log + "\r\n" + result);

            return result;
        }
        /// <summary>
        /// 获取企业永久授权码
        /// </summary>
        /// <param name="TmpAuthCode"></param>
        /// <returns></returns>
        public OapiServiceGetPermanentCodeResponse get_permanent_code(string TmpAuthCode)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/service/get_permanent_code?suite_access_token=" + get_suite_token().corp_token);
            OapiServiceGetPermanentCodeRequest req = new OapiServiceGetPermanentCodeRequest();
            req.TmpAuthCode = TmpAuthCode;
            string access_token = null;
            OapiServiceGetPermanentCodeResponse rsp = client.Execute(req, access_token);
            //Console.WriteLine(rsp.Body);

            return rsp;
        }

        /// <summary>  
        /// 根据当前日期 判断Access_Token 是否超期  如果超期返回新的Access_Token   否则返回之前的Access_Token  
        /// </summary>  
        /// <returns>Access_Token</returns>  
        public string IsExistAccess_Token()
        {

            string Token = string.Empty;
            DateTime YouXRQ;    //有效日期
            // 读取XML文件中的数据，并显示出来 ，注意文件路径  
            string path = System.AppContext.BaseDirectory;
            string filepath = path + "\\dingding\\Access_Token.xml";

            StreamReader str = new StreamReader(filepath, System.Text.Encoding.UTF8);
            XmlDocument xml = new XmlDocument();
            xml.Load(str);
            str.Close();
            str.Dispose();
            Token = xml.SelectSingleNode("xml").SelectSingleNode("Access_Token").InnerText;
            YouXRQ = Convert.ToDateTime(xml.SelectSingleNode("xml").SelectSingleNode("Access_YouXRQ").InnerText);

            LyCommon.WriteLog(YouXRQ.ToString());
            LyCommon.WriteLog(filepath);

            if (DateTime.Now > YouXRQ)
            {
                DateTime _youxrq = DateTime.Now;
                var mode = get_suite_token();
                xml.SelectSingleNode("xml").SelectSingleNode("Access_Token").InnerText = mode.corp_token;
                _youxrq = _youxrq.AddSeconds(int.Parse(mode.expires_in));
                xml.SelectSingleNode("xml").SelectSingleNode("Access_YouXRQ").InnerText = _youxrq.ToString();
                xml.Save(filepath);

                LyCommon.WriteLog(_youxrq.ToString(), "/Applogs/log.txt");

                Token = mode.corp_token;
                LyCommon.WriteLog("取token:" + Token );   //测试时用，正式时可注释掉
            }
            return Token;
        }
        public string SuiteTicket
        {
            get
            {
                string ret = string.Empty;
                // 读取XML文件中的数据，并显示出来 ，注意文件路径  
                string path = System.AppContext.BaseDirectory;
                string filepath = path + "\\dingding\\Access_Token.xml";

                StreamReader str = new StreamReader(filepath, System.Text.Encoding.UTF8);
                XmlDocument xml = new XmlDocument();
                xml.Load(str);
                str.Close();
                str.Dispose();
                ret = xml.SelectSingleNode("xml").SelectSingleNode("suite_ticket").InnerText;

                LyCommon.WriteLog("取SuiteTicket:" + ret);   //测试时用，正式时可注释掉
                return ret;

            }
            set
            {
                // 读取XML文件中的数据，并显示出来 ，注意文件路径  
                string path = System.AppContext.BaseDirectory;
                string filepath = path + "\\dingding\\Access_Token.xml";

                StreamReader str = new StreamReader(filepath, System.Text.Encoding.UTF8);
                XmlDocument xml = new XmlDocument();
                xml.Load(str);
                str.Close();
                str.Dispose();

                xml.SelectSingleNode("xml").SelectSingleNode("suite_ticket").InnerText = value;
                xml.Save(filepath);

                LyCommon.WriteLog("保存SuiteTicket:" + value);   //测试时用，正式时可注释掉

            }
        }


        [HttpGet("get/get_suite_token", Name = "get_suite_token")]
        public Corp_token get_suite_token()
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/service/get_suite_token");
            OapiServiceGetSuiteTokenRequest req = new OapiServiceGetSuiteTokenRequest();
            req.SuiteKey = suiteKey;
            req.SuiteSecret = suiteSecret;
            req.SuiteTicket = SuiteTicket;
            string access_token = null;
            OapiServiceGetSuiteTokenResponse rsp = client.Execute(req, access_token);
            //Console.WriteLine(rsp.Body);
            var token = new Corp_token();
            token.corp_token = rsp.SuiteAccessToken;
            token.expires_in = rsp.ExpiresIn.ToString();

            return token;
            //return rsp.SuiteAccessToken;
            //return "get_suite_token" + rsp.Body + "\r\naccess_token: " + access_token + "\r\nSuiteAccessToken" + rsp.SuiteAccessToken;
        }
        // GET: api/Call
        [HttpGet("get/get_corp_token", Name = "get_corp_token")]
        public string get_corp_token()
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/service/get_corp_token?suite_access_token=" + get_suite_token().corp_token);
            OapiServiceGetCorpTokenRequest req = new OapiServiceGetCorpTokenRequest();
            req.AuthCorpid = CorpId;
            string access_token = null;
            OapiServiceGetCorpTokenResponse rsp = client.Execute(req, access_token);
            //Console.WriteLine(rsp.Body);

            return rsp.Body;
            //return rsp.AccessToken;
        }
        [HttpGet("get/activate_suite", Name = "activate_suite")]
        public OapiServiceActivateSuiteResponse activate_suite(string PermanentCode)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/service/activate_suite?suite_access_token=" + get_suite_token().corp_token);
            OapiServiceActivateSuiteRequest req = new OapiServiceActivateSuiteRequest();
            req.SuiteKey = suiteKey;
            req.AuthCorpid = CorpId;
            req.PermanentCode = PermanentCode;
            string access_token = null;
            OapiServiceActivateSuiteResponse rsp = client.Execute(req, access_token);
            //Console.WriteLine(rsp.Body);

            return rsp;
        }
        [HttpGet]
        [Route("get/base")]
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }

        // GET: api/Call/5
        [HttpGet("{id}", Name = "Getid")]
        public string Get(int id)
        {
            return "value";
        }

        // POST: api/Call
        //[HttpPost]
        //public void Post([FromBody] string value)
        //{
        //}

        // PUT: api/Call/5
        [HttpPut("{id}")]
        public void Put(int id, [FromBody] string value)
        {
        }

        // DELETE: api/ApiWithActions/5
        [HttpDelete("{id}")]
        public void Delete(int id)
        {
        }
    }
}
